package com.ja.openchat.ui.chat;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.CameraUpdateFactory;
import com.amap.api.maps2d.MapView;
import com.amap.api.maps2d.UiSettings;
import com.amap.api.maps2d.model.BitmapDescriptorFactory;
import com.amap.api.maps2d.model.CameraPosition;
import com.amap.api.maps2d.model.LatLng;
import com.amap.api.maps2d.model.Marker;
import com.amap.api.maps2d.model.MarkerOptions;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.blankj.utilcode.util.ToastUtils;
import com.google.gson.JsonObject;
import com.ja.openchat.BR;
import com.ja.openchat.R;
import com.ja.openchat.ui.base.JaBaseActivity;
import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.interfaces.OnSelectListener;
import com.zy.openchat.core.manager.TelegramManager;
import com.zy.openchat.core.manager.TgResultBlock;
import com.zy.openchat.core.model.location.MsgLocationInfo;
import com.zy.openchat.core.model.message.ChatInfo;
import com.zy.openchat.core.model.message.MessageInfo;
import com.zy.openchat.core.model.user.UserInfo;

import java.io.File;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ShowLocationActivity extends JaBaseActivity {

    private String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CALL_PHONE,
            Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS};

    public static final String BUNDLE_LOCATION_INFO = "bundle_location_info";

    public static final String BUNDLE_MESSAGE_INFO = "bundle_message_info";

    public static void startActivity(Context context, MsgLocationInfo locationInfo){
        Intent intent = new Intent(context,ShowLocationActivity.class);
        intent.putExtra(BUNDLE_LOCATION_INFO,locationInfo);
        context.startActivity(intent);
    }

    public static void startActivity(Context context, MessageInfo messageInfo){
        Intent intent = new Intent(context,ShowLocationActivity.class);
        intent.putExtra(BUNDLE_MESSAGE_INFO,messageInfo);
        if(messageInfo.content!=null&&messageInfo.content.location!=null){
            intent.putExtra(BUNDLE_LOCATION_INFO,messageInfo.content.location);
        }
        context.startActivity(intent);
    }

    private MapView mMapView;
    private ImageView      mIvLocation;
    private AMap mAMap;
    private TextView tv_title;
    private TextView tv_message;
    private AMapLocationClient locationClient = null;
    private AMapLocationClientOption locationOption = new AMapLocationClientOption();
    private AMapLocation location;
    private AMapLocationListener mAMapLocationListener;
    private UiSettings mUiSettings;
    private float           zoom         = 14;//地图缩放级别
    private Marker mMarker, mLocationGpsMarker;


    @Override
    public int initContentView(Bundle savedInstanceState) {
        return R.layout.activity_show_location;
    }

    private MsgLocationInfo targetLocationInfo;
    private MessageInfo messageInfo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        targetLocationInfo = getIntent().getParcelableExtra(BUNDLE_LOCATION_INFO);
        messageInfo = getIntent().getParcelableExtra(BUNDLE_MESSAGE_INFO);
        if(targetLocationInfo==null&&messageInfo!=null&&messageInfo.content!=null){
            targetLocationInfo = messageInfo.content.location;
        }
        mMapView = (MapView) findViewById(R.id.map);
        tv_title = findViewById(R.id.tv_title);
        tv_message = findViewById(R.id.tv_message);
        mIvLocation = (ImageView) findViewById(R.id.iv_location);
        mMapView.onCreate(savedInstanceState);// 此方法必须重写
        mAMap = mMapView.getMap();
        mUiSettings = mAMap.getUiSettings();
        mUiSettings.setZoomControlsEnabled(false);//是否显示地图中放大缩小按钮
        mUiSettings.setMyLocationButtonEnabled(false); // 是否显示默认的定位按钮
        mUiSettings.setScaleControlsEnabled(true);//是否显示缩放级别
        mAMap.setMyLocationEnabled(false);// 是否可触发定位并显示定位层

        setTitle(getString(R.string.location_text));
        ImageView barRight = findViewById(R.id.iv_bar_right);
        barRight.setImageResource(R.drawable.nav_point_more);
        barRight.setVisibility(View.VISIBLE);
        barRight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showMore();
            }
        });


        mAMapLocationListener = new AMapLocationListener() {
            @Override
            public void onLocationChanged(AMapLocation loc) {
                try {
                    if (null != loc) {
                        stopLocation();
                        if (loc.getErrorCode() == 0) {//可在其中解析amapLocation获取相应内容。
                            location = loc;
                            doWhenLocationSucess();
                        } else {
                            //定位失败时，可通过ErrCode（错误码）信息来确定失败的原因，errInfo是错误信息，详见错误码表。
                            Log.e("AmapError", "location Error, ErrCode:"
                                    + loc.getErrorCode() + ", errInfo:"
                                    + loc.getErrorInfo());

                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        };

        mAMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
            @Override
            public void onCameraChangeFinish(CameraPosition cameraPosition) {
                if (null != location && null != cameraPosition) {
                    mIvLocation.setImageResource(R.mipmap.location_gps_black);
                    zoom = cameraPosition.zoom;
                }
            }

            @Override
            public void onCameraChange(CameraPosition cameraPosition) {

            }
        });
        mIvLocation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mIvLocation.setImageResource(R.mipmap.location_gps_green);
                isClickToLocation = true;
                if (null == location) {
                    startLocation();
                } else {
                    doWhenLocationSucess();

                }
            }
        });

        if(targetLocationInfo!=null){
            refleshTargetLocationMark(targetLocationInfo.latitude,targetLocationInfo.longitude);
            moveMapCamera(targetLocationInfo.latitude,targetLocationInfo.longitude);

            try {
                GeocodeSearch geocoderSearch = new GeocodeSearch(this);
                geocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener(){

                    @Override
                    public void onGeocodeSearched(GeocodeResult result, int rCode) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
                        tv_message.setText(result.getRegeocodeAddress().getFormatAddress());
                    }});
                LatLonPoint   lp = new LatLonPoint(targetLocationInfo.latitude,targetLocationInfo.longitude);
                RegeocodeQuery query = new RegeocodeQuery(lp, 200,GeocodeSearch.AMAP);
                geocoderSearch.getFromLocationAsyn(query);
            }catch (Exception e){
                e.printStackTrace();
            }

            findViewById(R.id.daohangBtn).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    showMoreDaohang();
                }
            });

            doSearchQuery();
        }
        initPermission();
    }

    private void doSearchQuery() {
        if(targetLocationInfo==null){
            return;
        }
        try {
            PoiSearch.Query query = new PoiSearch.Query("", "", "");
            query.setPageSize(1);
            query.setPageNum(0);
            PoiSearch poisearch = new PoiSearch(this, query);
            poisearch.setOnPoiSearchListener(new PoiSearch.OnPoiSearchListener() {
                @Override
                public void onPoiSearched(PoiResult poiResult, int resultCode) {
                    if (resultCode == AMapException.CODE_AMAP_SUCCESS) {
                        if (poiResult != null && poiResult.getPois().size() > 0) {
                            List<PoiItem> poiItems = poiResult.getPois();
                            tv_title.setText(poiItems.get(0).getTitle());
                        }
                    }
                }

                @Override
                public void onPoiItemSearched(PoiItem poiItem, int i) {

                }
            });
            poisearch.setBound(new PoiSearch.SearchBound(new LatLonPoint(targetLocationInfo.latitude,targetLocationInfo.longitude), 500, true));
            poisearch.searchPOIAsyn();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private boolean isClickToLocation = false;

    private void doWhenLocationSucess(){
        refleshLocationMark(location.getLatitude(), location.getLongitude());
        if(targetLocationInfo==null||isClickToLocation){
            moveMapCamera(location.getLatitude(), location.getLongitude());
        }
        isClickToLocation = false;
    }

    private void refleshLocationMark(double latitude, double longitude) {
        if (mLocationGpsMarker == null) {
            mLocationGpsMarker = mAMap.addMarker(new MarkerOptions()
                    .position(new LatLng(latitude, longitude))
                    .icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                            .decodeResource(getResources(), R.mipmap.location_blue)))
                    .draggable(true));
        }
        mLocationGpsMarker.setPosition(new LatLng(latitude, longitude));
        mAMap.invalidate();
    }


    private void refleshTargetLocationMark(double latitude, double longitude) {
        if (mMarker == null) {

            mMarker = mAMap.addMarker(new MarkerOptions()
                    .position(new LatLng(latitude, longitude))
                    .icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                            .decodeResource(getResources(), R.mipmap.arm)))
                    .draggable(true));
        }
        mMarker.setPosition(new LatLng(latitude, longitude));
        mAMap.invalidate();
    }


    private void moveMapCamera(double latitude, double longitude) {
        if (null != mAMap) {
            mAMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), zoom));
        }
    }

    public void showMoreDaohang(){
        if(targetLocationInfo==null){
            return;
        }
        new XPopup.Builder(this).asBottomList(null, new String[]{getString(R.string.gaode_map),getString(R.string.tencent_map),getString(R.string.baidu_map)}, new OnSelectListener() {
            @Override
            public void onSelect(int position, String text) {
                switch (position){
                    case 0:
                        if (isAvilible("com.autonavi.minimap")) {
                            Intent intent = new Intent();
                            intent.setAction(Intent.ACTION_VIEW);
                            intent.addCategory(Intent.CATEGORY_DEFAULT);

                            //将功能Scheme以URI的方式传入data
                            Uri uri = Uri.parse("androidamap://navi?sourceApplication=appname&poiname=fangheng&lat=" + targetLocationInfo.latitude + "&lon=" + targetLocationInfo.longitude + "&dev=1&style=2");
                            intent.setData(uri);

                            //启动该页面即可
                            startActivity(intent);
                        } else {
                            Toast.makeText(ShowLocationActivity.this, getString(R.string.not_installed_gaode_map), Toast.LENGTH_LONG).show();
                            download("com.autonavi.minimap");
                        }
                        break;
                    case 1:
                        Intent intent = new Intent();
                        intent.setAction(Intent.ACTION_VIEW);
                        intent.addCategory(Intent.CATEGORY_DEFAULT);
                        //将功能Scheme以URI的方式传入data
                        Uri uri = Uri.parse("qqmap://map/routeplan?type=drive&to=我的目的地&tocoord=" + targetLocationInfo.latitude + "," + targetLocationInfo.longitude);
                        intent.setData(uri);
                        if (intent.resolveActivity(getPackageManager()) != null) {
                            //启动该页面即可
                            startActivity(intent);
                        } else {
                            Toast.makeText(ShowLocationActivity.this, getString(R.string.not_installed_tenxun_map), Toast.LENGTH_LONG).show();
                        }
                        break;
                    case 2:
                        if (isAvilible("com.baidu.BaiduMap")) {//传入指定应用包名
                            try {
                                Intent intent1 = Intent.getIntent("intent://map/direction?" +
                                        "destination=latlng:" + targetLocationInfo.latitude + "," + targetLocationInfo.longitude + "|name:我的目的地" +    //终点
                                        "&mode=driving&" +     //导航路线方式
                                        "&src=appname#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end");
                                startActivity(intent1); //启动调用
                            } catch (URISyntaxException e) {
                                Log.e("intent", e.getMessage());
                            }
                        } else {//未安装
                            //market为路径，id为包名
                            //显示手机上所有的market商店
                            Toast.makeText(ShowLocationActivity.this, getString(R.string.not_installed_baidu_map), Toast.LENGTH_LONG).show();
                            download("com.baidu.BaiduMap");
                        }
                        break;
                }
            }
        }).show();
    }

    private void download(String packageName){
        Uri uri1 = Uri.parse("market://details?id="+packageName);
        Intent intent1 = new Intent(Intent.ACTION_VIEW, uri1);
        if (intent1.resolveActivity(getPackageManager()) != null){
            startActivity(intent1);
        }
    }

    private void showMore(){
        if(messageInfo==null){
            return;
        }
        new XPopup.Builder(this).asBottomList(null, new String[]{getString(R.string.send_location_to_friend),getString(R.string.collect_text)}, new OnSelectListener() {
            @Override
            public void onSelect(int position, String text) {
                ArrayList<MessageInfo> msgs = new ArrayList<>();
                msgs.add(messageInfo);
                if(position==0){
                    Intent intent = new Intent(ShowLocationActivity.this, ForwardActivity.class);
                    intent.putExtra("messages", msgs);
                    startActivity(intent);
                }else{
                    TelegramManager.getTelegramManager().createPrivateChat(ShowLocationActivity.this, UserInfo.getUserInfo().id, new TgResultBlock<ChatInfo>() {
                        @Override
                        public void onResult(Map<String, Object> request, JsonObject response, ChatInfo obj) {
                            if (obj != null) {
                                TelegramManager.getTelegramManager().forwardMessages(ShowLocationActivity.this,obj.id,msgs);
                                ToastUtils.showShort(getString(R.string.collected_text));
                            }else{
                                ToastUtils.showShort(getString(R.string.request_error));
                            }
                        }

                        @Override
                        public void onTimeout(Map<String, Object> request) {
                            ToastUtils.showShort(getString(R.string.request_error));
                        }
                    });
                }
            }
        }).show();
    }

    private boolean isAvilible(String packageName) {
        return new File("/data/data/" + packageName).exists();
    }


    private void initPermission() {

        // 版本判断。当手机系统大于 23 时，才有必要去判断权限是否获取
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 检查该权限是否已经获取
            int i = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[0]);
            int l = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[1]);
            int m = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[2]);
            int n = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[3]);
            // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
            if (i != PackageManager.PERMISSION_GRANTED || l != PackageManager.PERMISSION_GRANTED || m != PackageManager.PERMISSION_GRANTED ||
                    n != PackageManager.PERMISSION_GRANTED) {
                // 如果没有授予该权限，就去提示用户请求
                ActivityCompat.requestPermissions(this, permissions, 321);
            } else {
                startLocation();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopLocation();
        mMapView.onDestroy();
    }

    @Override
    public void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        try {
            mMapView.onSaveInstanceState(outState);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 初始化定位
     */
    private void initLocation() {
        try {
            if (null == locationClient) {
                //初始化client
                locationClient = new AMapLocationClient(this.getApplicationContext());
                //设置定位参数
                locationClient.setLocationOption(getDefaultOption());
                // 设置定位监听
                locationClient.setLocationListener(mAMapLocationListener);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 默认的定位参数
     */
    private AMapLocationClientOption getDefaultOption() {
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.setGpsFirst(false);//可选，设置是否gps优先，只在高精度模式下有效。默认关闭
        mOption.setHttpTimeOut(30000);//可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setInterval(2000);//可选，设置定位间隔。默认为2秒
        mOption.setNeedAddress(true);//可选，设置是否返回逆地理地址信息。默认是true
        mOption.setOnceLocation(false);//可选，设置是否单次定位。默认是false
        mOption.setOnceLocationLatest(false);//可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
        AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可选， 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        mOption.setSensorEnable(false);//可选，设置是否使用传感器。默认是false
        mOption.setWifiScan(true); //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
        mOption.setMockEnable(true);//如果您希望位置被模拟，请通过setMockEnable(true);方法开启允许位置模拟
        return mOption;
    }

    /**
     * 开始定位
     */
    public void startLocation() {
        initLocation();
        // 设置定位参数
        locationClient.setLocationOption(locationOption);
        // 启动定位
        locationClient.startLocation();
    }

    /**
     * 停止定位
     */
    private void stopLocation() {
        if (null != locationClient) {
            locationClient.stopLocation();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 321) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    //如果没有获取权限，那么可以提示用户去设置界面--->应用权限开启权限
                    Toast toast = Toast.makeText(this, "请开启权限", Toast.LENGTH_LONG);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                } else {
                    //获取权限成功
                    startLocation();
                }
            }
        }
    }

    @Override
    public int initVariableId() {
        return BR.viewModel;
    }

}
